from pickle import TRUE
import tkinter as tk
import random
from tkinter import font

# 全局变量，存储随机文本列表，可以从外部读取和修改
RANDOM_TEXTS = [
    "今天天气真好！", "保持好心情！", "继续加油！", "你已经做得很棒了！", 
    "慢慢来，不着急，我支持你。", "每一天都是新的开始，加油！", 
    "你的努力，总有一天会被看见。", "相信自己，你远比自己想象的更强大。", 
    "没关系的，一切都会好起来的。", "如果累了，就允许自己休息一下。", 
    "你已经很棒了，别太苛求自己。", "事情总会一件一件解决的。", 
    "深呼吸，先专注当下这一刻。", "你本身就是一道光。", 
    "无论发生什么，你都不是一个人。", "生活虽然普通，但也要乐在其中。", 
    "今天也会有好事发生的。", "你值得所有美好的事物。", 
    "向前看，好运气正在路上呢！", "打起精神来，惊喜可能就在下一秒。", 
    "你是最棒的，没什么能难倒你！", "像太阳一样，暖暖地发光吧！", 
    "继续保持你的可爱，世界都会对你微笑。", "每一步都是进步，无论多小。", 
    "你的存在让世界变得更美好。", "困难只是暂时的，你会克服的。", 
    "给自己一个微笑，心情会变好的。", "你已经走了很远的路，真了不起！", 
    "相信过程，结果会自然到来。", "你的坚韧让人敬佩。", 
    "今天也是充满希望的一天！", "小小的挫折是为了更大的成功。", 
    "你的笑容很有感染力，多笑笑吧！", "一切都在慢慢变好，你能感受到的。", 
    "你是独一无二的，这本身就很有价值。", "保持耐心，美好的事物值得等待。", 
    "你的善良和努力都不会被辜负。", "每一天都是改变的机会。", 
    "你比昨天又进步了一点呢！", "放轻松，事情没有想象中那么难。", 
    "你的潜力是无限的，继续挖掘吧！", "阳光总在风雨后，坚持就是胜利。", 
    "你正在成为更好的自己，这很酷！", "生活因你而更加精彩。", 
    "别忘了，你一直都很优秀。", "今天的你也很努力，辛苦了！", 
    "好事正在酝酿，准备迎接吧！", "你的坚持终将收获美好。", 
    "保持积极，好运自然会来。", "你是生活的勇士，继续前进！", 
    "每一个今天都是余生的第一天。", "你的温暖能融化所有冰雪。", 
    "慢慢来，比较快。", "你已经很棒了，我为你骄傲！", 
    "未来可期，你值得最好的。", "你的能量超乎你想象。", 
    "一切都是最好的安排。", "爱你所爱，行你所行。", 
    "心若向阳，无畏悲伤。", "你就是自己的太阳。",
    "生活很美好，记得停下来欣赏。", "你的进步我看在眼里，喜在心里。", 
    "别担心，你有能力处理好一切。", "每一天都是上天赐予的礼物。", 
    "你的勇气让人钦佩。", "相信自己的选择，它们都有意义。", 
    "微笑是最好的化妆品。", "你让周围的人都感到温暖。", 
    "坚持做自己，就是最棒的。", "今天的困难是明天的财富。", 
    "你的心态决定你的世界。", "放松心情，享受当下的宁静。", 
    "你有改变世界的力量。", "每一次尝试都是一次成长。", 
    "你是如此特别，值得被珍惜。", "放下包袱，轻装上阵。", 
    "你的热情能感染每一个人。", "感恩遇见，珍惜拥有。", 
    "你比想象中更坚强。", "美好正在悄悄靠近你。", 
    "给自己一点掌声，你做得很好。", "乌云后面总是灿烂的阳光。", 
    "你的善良是世界需要的温暖。", "保持好奇，发现生活的美。", 
    "你有无限的可能性。", "简单的生活也有大大的幸福。", 
    "你的努力不会被辜负。", "每一天都值得被认真对待。", 
    "你是生命的舞者，跳出自己的精彩。", "放下过去，拥抱现在。", 
    "你的存在就是最大的意义。", "保持希望，明天会更好。", 
    "你有能力创造自己想要的生活。", "小小的幸福也值得庆祝。", 
    "你的真诚是最感动人的品质。", "相信时间会给出最好的答案。", 
    "你是如此勇敢，面对一切困难。", "内心的平静是最强大的力量。", 
    "你的微笑能照亮整个世界。", "每一天都是重新开始的机会。", 
    "你有让生活变得更美好的能力。", "保持谦逊，持续学习。", 
    "你的坚持会开出最美的花。", "简单的心，快乐的生活。", 
    "你是命运的主宰者。", "内心的光芒会指引你方向。", 
    "你的善良终将得到回报。", "珍惜当下，感恩拥有。", 
    "你有独特的魅力，自信展现。", "风雨过后必见彩虹。"
]

class PopupWarmTip:
    def __init__(self):
        self.popups = []  # 存储所有弹窗实例
        self.root = None  # 主窗口引用
        # 更现代的颜色方案
        self.colors = [
            "#A65B52", "#8C4A45", "#B3726A", "#73575A",
            "#6D4F3F", "#5A4F4D", "#4A4A4F", "#3A4A5A",
            "#3F5A6F", "#3A5956", "#405A52", "#4A5D6A",
            "#5D536F", "#6A506F", "#7A6365", "#8C7A66",
            "#9C8B72", "#A99F93", "#8A8A7F", "#6B6B6B"
        ]
    
    def generate_random_text(self):
        """生成随机文本内容"""
        return random.choice(RANDOM_TEXTS)
    
    def generate_random_color(self):
        """生成随机背景颜色"""
        return random.choice(self.colors)
    
    def get_text_color(self, bg_color):
        """根据背景颜色获取随机的文字颜色，确保足够的对比度"""
        # 定义一组明亮的文字颜色，确保与背景有足够对比度
        all_text_colors = [
            "#F8B4CB", "#FFA7A7", "#FFB8A8", "#F8D7C9",
            "#FFD4A4", "#FFE8A4", "#F5F0A3", "#D6E6B6",
            "#B8E0C3", "#A8E1E6", "#9CD0E6", "#A7C8E7",
            "#C4B9E6", "#D8BFD8", "#E6C9CA", "#E9D6BC",
            "#F0E2D3", "#E8EDDF", "#D2E5E1", "#DFECE9"
        ]
        
        # 从颜色列表中随机选择一个颜色
        return random.choice(all_text_colors)
    
    def generate_random_position(self, width, height):
        """生成随机位置"""
        # 获取屏幕尺寸
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        
        # 确保弹窗不会超出屏幕
        x = random.randint(0, screen_width - width)
        y = random.randint(0, screen_height - height)
        
        return x, y
    
    def create_popup(self, title="提示", width=300, height=120, display_time=5, marquee=True):
        """创建单个弹窗
        
        Args:
            title: 窗口标题
            width: 窗口宽度
            height: 窗口高度
            display_time: 显示时间(秒)
            marquee: 是否启用跑马灯效果
        """
        if self.root is None:
            self.root = tk.Tk()
            self.root.withdraw()  # 隐藏主窗口
        
        # 创建弹窗窗口
        popup = tk.Toplevel(self.root)
        popup.overrideredirect(True)  # 去掉窗口边框和标题栏
        popup.attributes('-topmost', True)  # 确保弹窗显示在最前面
        
        # 添加立体感的效果
        self._add_glass_effect(popup, width, height)
        
        # 提前设置鼠标悬停标志
        popup.hovering = False
        popup._scroll_id = None  # 初始化滚动ID
        
        # 设置窗口属性
        text = self.generate_random_text()
        bg_color = self.generate_random_color()
        fg_color = self.get_text_color(bg_color)
        x, y = self.generate_random_position(width, height)
        
        popup.geometry(f"{width}x{height}+{x}+{y}")
        
        # 创建一个Frame作为容器，设置样式，添加内边距以增强立体感
        content_frame = tk.Frame(popup, bg=bg_color, bd=0, highlightthickness=0)
        content_frame.pack(fill="both", expand=True, padx=3, pady=3)
        
        # 添加窗口拖动功能
        def start_drag(event):
            popup.x = event.x
            popup.y = event.y
            
        def on_drag(event):
            x = popup.winfo_pointerx() - popup.x
            y = popup.winfo_pointery() - popup.y
            popup.geometry(f"+{x}+{y}")
        
        # 美化标题标签
        title_label = tk.Label(
            content_frame, 
            text=title, 
            font=font.Font(family="KaiTi", size=14, weight="bold"),
            bg=bg_color, 
            fg=fg_color, 
            anchor="center",
            pady=10
        )
        title_label.pack(fill="x", padx=15)
        
        # 绑定标题栏拖动事件
        title_label.bind("<Button-1>", start_drag)
        title_label.bind("<B1-Motion>", on_drag)
        
        # 添加分隔线
        separator = tk.Frame(content_frame, height=1, bg=fg_color, bd=0)
        separator.pack(fill="x", padx=15, pady=(0, 10))
        
        # 创建滚动区域
        scroll_frame = tk.Frame(content_frame, bg=bg_color)
        scroll_frame.pack(fill="both", expand=True, padx=15, pady=(0, 15))
        
        # 根据marquee参数决定是否设置wraplength（控制是否换行）
        if marquee:
            # 跑马灯模式：不允许换行，文字在一行内滚动
            content_label = tk.Label(
                scroll_frame, 
                text=text, 
                font=font.Font(family="KaiTi", size=11),
                bg=bg_color, 
                fg=fg_color,
                justify="left",
                padx=10,
                pady=10,
                anchor="w"
            )
        else:
            # 非跑马灯模式：允许文字自动换行
            content_label = tk.Label(
                scroll_frame, 
                text=text, 
                font=font.Font(family="KaiTi", size=11),
                bg=bg_color, 
                fg=fg_color,
                justify="left",
                padx=10,
                pady=10,
                wraplength=width - 70,  # 设置适当的换行宽度
                anchor="w"
            )
        content_label.pack(side="left", fill="both", expand=True)
        
        # 初始化hovering属性
        popup.hovering = False
        
        # 设置是否需要滚动
        need_scroll = False
        text_width = 0
        container_width = 0
        
        # 启动跑马灯效果
        if marquee:
            # 检查文本是否需要滚动
            content_label.update_idletasks()  # 确保获取正确的宽度
            text_width = content_label.winfo_reqwidth()
            container_width = width - 70  # 容器实际可用宽度
            
            if text_width > container_width:
                need_scroll = True
                # 计算文本宽度和容器宽度的差值
                diff = text_width - container_width
                
                # 初始位置
                x_pos = 0
                direction = -1  # 滚动方向（-1为向左）
                scroll_speed = 1  # 降低速度使滚动更平滑
                scroll_pause = 20  # 减小暂停时间使滚动更流畅
                
                # 滚动函数
                def scroll_text():
                    nonlocal x_pos, direction
                    
                    # 检查是否到达边界并改变方向
                    if x_pos <= -diff - 20:  # 左边边界
                        direction = 1  # 向右滚动
                    elif x_pos >= 20:  # 右边边界
                        direction = -1  # 向左滚动
                    
                    # 更新位置
                    x_pos += direction * scroll_speed
                    content_label.place(x=x_pos, y=0)
                    
                    # 继续滚动，只要弹窗存在就继续
                    if popup.winfo_exists():
                        popup._scroll_id = scroll_frame.after(scroll_pause, scroll_text)
                
                # 将标签改为绝对定位以便滚动
                content_label.pack_forget()
                content_label.place(x=x_pos, y=0, height=content_label.winfo_reqheight())
                
                # 开始滚动
                scroll_text()
            else:
                # 文本宽度适中，居中显示即可
                content_label.pack(fill="both", expand=True)
        else:
            # 不启用跑马灯，直接居中显示
            content_label.pack(fill="both", expand=True)  # 移除错误的wraplength参数
        
        def on_enter(event):
            popup.hovering = True
            # 鼠标悬停时轻微改变透明度，增加效果
            popup.attributes('-alpha', 0.98)
            # 鼠标悬停时将窗口置顶
            popup.attributes('-topmost', True)
            # 添加果冻弹跳效果
            if hasattr(popup, '_jelly_animating') and popup._jelly_animating:
                return  # 如果已经在动画中，不重复触发
            
            popup._jelly_animating = True
            original_width = width
            original_height = height
            original_x, original_y = popup.winfo_x(), popup.winfo_y()
            
            # 更加自然的果冻动画缩放序列 - 使用更细微的变化和更多的过渡步骤
            jelly_sequence = [
                (original_width * 1.015, original_height * 0.985), # 非常轻微横向拉伸，纵向压缩
                (original_width * 0.992, original_height * 1.008), # 非常轻微横向压缩，纵向拉伸
                (original_width * 1.008, original_height * 0.992), # 微小幅度横向拉伸，纵向压缩
                (original_width * 0.996, original_height * 1.004), # 极微小幅度横向压缩，纵向拉伸
                (original_width * 1.004, original_height * 0.996), # 更细微的横向拉伸，纵向压缩
                (original_width * 0.998, original_height * 1.002), # 几乎察觉不到的横向压缩，纵向拉伸
                (original_width, original_height)                  # 恢复原始大小
            ]
            
            # 使用更短的时间间隔让动画更加流畅自然
            animation_delay = 25
            
            def animate_jelly(step=0):
                if step < len(jelly_sequence) and popup.winfo_exists():
                    new_width, new_height = jelly_sequence[step]
                    # 计算新位置以保持中心不变
                    new_x = original_x + (original_width - new_width) // 2
                    new_y = original_y + (original_height - new_height) // 2
                    popup.geometry(f"{int(new_width)}x{int(new_height)}+{int(new_x)}+{int(new_y)}")
                    # 继续下一步动画
                    popup.after(animation_delay, lambda: animate_jelly(step + 1))
                else:
                    # 动画结束，恢复原始大小和位置
                    if popup.winfo_exists():
                        popup.geometry(f"{original_width}x{original_height}+{original_x}+{original_y}")
                        popup._jelly_animating = False
            
            # 开始果冻动画
            animate_jelly()
        
        def on_leave(event):
            popup.hovering = False
            # 鼠标离开时恢复透明度
            popup.attributes('-alpha', 0.95)
            # 移除恢复滚动的代码，因为滚动不会被暂停
        
        # 添加拖拽功能
        def start_drag(event):
            popup.x = event.x
            popup.y = event.y
        
        def on_drag(event):
            x = popup.winfo_pointerx() - popup.x
            y = popup.winfo_pointery() - popup.y
            popup.geometry(f"+{x}+{y}")
        
        # 绑定事件
        popup.bind("<Enter>", on_enter)
        popup.bind("<Leave>", on_leave)
        content_frame.bind("<Button-1>", start_drag)
        content_frame.bind("<B1-Motion>", on_drag)
        
        # 设置窗口的透明度来增强视觉效果
        popup.attributes('-alpha', 0.95)
        
        # 添加到弹窗列表
        self.popups.append(popup)
        
        # 使用after方法在主线程中控制弹窗关闭时间
        self.root.after(int(display_time * 1000), lambda p=popup: self._check_close_popup(p))
        
        return popup
    
    def _check_close_popup(self, popup):
        """在主线程中检查是否可以关闭弹窗"""
        # 确保弹窗存在
        if popup.winfo_exists():
            # 检查是否正在悬停 - 鼠标悬停时不关闭弹窗
            if hasattr(popup, 'hovering') and popup.hovering:
                # 当鼠标悬停时，每500毫秒检查一次，但不关闭弹窗
                # 这样只要用户一直悬停，弹窗就会一直保持显示
                self.root.after(500, lambda p=popup: self._check_close_popup(p))
            else:
                # 鼠标未悬停时执行关闭动画
                self._fade_out_popup(popup)
    
    def _fade_out_popup(self, popup):
        """弹窗淡出动画"""
        alpha = popup.attributes('-alpha')
        if alpha > 0:
            popup.attributes('-alpha', alpha - 0.05)
            self.root.after(30, lambda p=popup: self._fade_out_popup(p))
        else:
            # 关闭弹窗
            if popup in self.popups:
                self.popups.remove(popup)
            popup.destroy()
    
    def _add_glass_effect(self, popup, width, height):
        """为窗口添加立体效果"""
        pass
    
    def show_multiple_popups(self, count=1, title="提示", width=400, height=150, display_time=5, interval=1, marquee=True):
        """显示多个弹窗，逐个弹出
        
        Args:
            count: 弹窗数量
            title: 窗口标题
            width: 窗口宽度
            height: 窗口高度
            display_time: 显示时间(秒)
            interval: 弹窗间隔时间(秒)
            marquee: 是否启用跑马灯效果
        """
        if self.root is None:
            self.root = tk.Tk()
            self.root.withdraw()  # 隐藏主窗口
        
        # 重置弹窗列表
        self.popups = []
        self.total_count = count
        self.current_count = 0
        self.popup_interval = interval
        
        # 使用after方法逐个创建弹窗
        def create_next_popup():
            if self.current_count < self.total_count:
                # 创建弹窗时添加淡入效果
                popup = self.create_popup(title=title, width=width, height=height, display_time=display_time, marquee=marquee)
                # 淡入动画
                popup.attributes('-alpha', 0)
                def fade_in():
                    alpha = popup.attributes('-alpha')
                    if alpha < 0.95 and popup.winfo_exists():
                        popup.attributes('-alpha', alpha + 0.1)
                        self.root.after(50, fade_in)
                fade_in()
                
                self.current_count += 1
                # 安排下一个弹窗
                self.root.after(int(self.popup_interval * 1000), create_next_popup)
            else:
                # 所有弹窗创建完成，启动监控
                monitor_popups()
        
        # 检测所有弹窗是否关闭
        def monitor_popups():
            # 检查弹窗列表是否为空
            if not self.popups:
                # 所有弹窗都已关闭，退出主循环
                try:
                    self.root.quit()
                except:
                    pass
            else:
                # 继续检查
                self.root.after(1000, monitor_popups)
        
        # 开始创建第一个弹窗
        create_next_popup()
        
        # 启动主循环
        self.root.mainloop()


# 示例用法
if __name__ == "__main__":
    popup_manager = PopupWarmTip()
    # 显示10个弹窗，每个弹窗显示10秒，间隔0.1秒，启用跑马灯效果
    popup_manager.show_multiple_popups(
        count=100, 
        title="♥温馨提示♥", 
        width=250, 
        height=150, 
        display_time=15, 
        interval=0.1,
        marquee=True
    )